package com.kun.framework.core;

import com.kun.framework.core.compoment.AlertMessage;
import com.kun.framework.core.config.BeanContext;
import com.kun.framework.core.config.WebViewConfiguration;
import com.kun.framework.core.factory.StageSingletonFactory;
import javafx.application.Application;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

/**
 * 程序抽象类
 *
 * @author gzc
 * @since 2024/9/21
 **/
public abstract class AbstractApplication extends Application {
    private static final Logger log = LoggerFactory.getLogger(AbstractApplication.class);
    /**
     * 程序主窗口对象
     */
    protected static Stage APP_STAGE;
    /**
     * 程序启动后延迟回调时间（毫秒）
     */
    protected static int startupBeforeCallbackTimed = 1000;

    public static Stage getAppStage() {
        return AbstractApplication.APP_STAGE;
    }

    private void setAppStage(Stage stage) {
        AbstractApplication.APP_STAGE = stage;
    }

        protected Stage createAppStage() {
        return null;
    }

    /**
     * 运行程序
     *
     * @param args 系统参数
     * @param cls  入口类
     */
    public static void run(Class<? extends AbstractApplication> cls, String[] args,
                           Function<String, URL> loadUrlFunction) {
        WebViewConfiguration.init();
        StageSingletonFactory.init(cls, loadUrlFunction);
        launch(cls, args);
    }

    /**
     * 开始初始化程序
     *
     * @throws Exception 异常
     */
    protected void doInit() throws Exception {

    }

    /**
     * 开始启动程序
     *
     * @param primaryStage 主窗口
     * @throws Exception 异常
     */
    protected abstract void doStart(Stage primaryStage) throws Exception;

    /**
     * 开始停止程序
     */
    protected void doStartupBefore() throws Exception {

    }

    /**
     * 开始停止程序
     *
     * @throws Exception 异常
     */
    protected void doStop() throws Exception {

    }

    /**
     * 初始化程序
     *
     * @throws Exception 异常
     */
    @Override
    public final void init() throws Exception {
        log.info("开始执行初始化程序回调函数...");
        BeanContext.init();
        doInit();
        log.info("结束执行初始化程序回调函数");
    }

    /**
     * {@link #init()}方法执行结束后调用
     *
     * @param primaryStage 主窗口
     * @throws Exception 异常
     */
    @Override
    public final void start(Stage primaryStage) throws Exception {
        log.info("开始启动程序...");
        Stage stage = createAppStage();
        setAppStage(stage != null ? stage : primaryStage);
        Stage appStage = getAppStage();
        doStart(appStage);
        log.info("启动程序成功");
        // 异步回调
        CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(startupBeforeCallbackTimed);
                log.info("开始执行程序启动后回调函数...");
                BeanContext.startupBefore();
                doStartupBefore();
                log.info("结束执行程序启动后回调函数");
            } catch (Exception e) {
                log.error("程序启动后回调发生异常 -> ", e);
                AlertMessage.error("程序启动后回调发生异常", e);
            }
        });
    }

    /**
     * 停止程序
     *
     * @throws Exception 异常
     */
    @Override
    public final void stop() throws Exception {
        log.info("开始执行停止程序回调函数...");
        BeanContext.destroy();
        doStop();
        log.info("结束执行停止程序回调函数");
    }

}
